﻿#pragma once

#include "SARibbon/SARibbon.h"

#include "ui_MainWindow.h"

#include <QAction.h>
#include <gp_Pnt.hxx>
#include <gp_Ax2.hxx>
#include <TopoDS_Shape.hxx>
#include "Render/QIVtkSelectionPipeline.h"
#include "gp_Trsf.hxx"

#include "RWTools.h"
#include <QStandardItemModel>

class HistoryManager;
class FeatureShape;
class ShapeOperation;
class ExpressionManager;
class SARibbonBar;
class SARibbonQuickAccessBar;
class QSketchManager;
class WindowInteractorStyle;
class TempActorManager;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindowClass; };
QT_END_NAMESPACE

class MainWindow : public SARibbonMainWindow
{
	Q_OBJECT

public:
	friend class HistoryManager;

	MainWindow(QWidget *parent = nullptr);
	~MainWindow();

	// 创建不同形状的Actor
	Handle(QIVtkSelectionPipeline) createCube(float length, float width, float height);
	Handle(QIVtkSelectionPipeline) createSphere(float radius);
	Handle(QIVtkSelectionPipeline) createCylinder(float radius, float height);
	Handle(QIVtkSelectionPipeline) createTorus(float radiusOuter, float radiusInner);
	Handle(QIVtkSelectionPipeline) createCone(float radius1, float radius2, float height);
	Handle(QIVtkSelectionPipeline) createLine(const gp_Pnt& p1, const gp_Pnt& p2);
	Handle(QIVtkSelectionPipeline) createArcCircle(const gp_Pnt& start, const gp_Pnt& tangent, const gp_Pnt& end);
	Handle(QIVtkSelectionPipeline) createCircle(const gp_Pnt& center, float radius, const gp_Dir& normal);
    Handle(QIVtkSelectionPipeline) createEllipse(const gp_Ax2& axis, float majorRadius, float minorRadius);
    Handle(QIVtkSelectionPipeline) createParabola(const gp_Ax2& axis, float focal, float startLen, float endLen);
	Handle(QIVtkSelectionPipeline) createHyperbola(const gp_Ax2& axis, float majorRadius, float minorRadius, float startLen, float endLen);
	Handle(QIVtkSelectionPipeline) createRectangle(const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3, const gp_Pnt& p4);

	// 根据feature shape创建对应的Actor
    Handle(QIVtkSelectionPipeline) createActorFromFeatureShape(FeatureShape* shape, bool bAddToCache);

	// 更新Actor的大小
	Handle(QIVtkSelectionPipeline) UpdateCubeActor(Handle(QIVtkSelectionPipeline) actor, float length, float width, float height);
	Handle(QIVtkSelectionPipeline) UpdateSphereActor(Handle(QIVtkSelectionPipeline) actor, float radius);
	Handle(QIVtkSelectionPipeline) UpdateCylinderActor(Handle(QIVtkSelectionPipeline) actor, float radius, float height);
	Handle(QIVtkSelectionPipeline) UpdateTorusActor(Handle(QIVtkSelectionPipeline) actor, float radiusOuter, float radiusInner);
	Handle(QIVtkSelectionPipeline) UpdateConeActor(Handle(QIVtkSelectionPipeline) actor, float radius1, float radius2, float height);
	Handle(QIVtkSelectionPipeline) UpdateLineActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& p1, const gp_Pnt& p2);
    Handle(QIVtkSelectionPipeline) UpdateCircleActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& start, const gp_Pnt& tangent, const gp_Pnt& end);
    Handle(QIVtkSelectionPipeline) UpdateEllipseActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float majorRadius, float minorRadius);
    Handle(QIVtkSelectionPipeline) UpdateParabolaActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float focal, float startLen, float endLen);
    Handle(QIVtkSelectionPipeline) UpdateHyperbolaActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float majorRadius, float minorRadius, float startLen, float endLen);

	// 创建Actor-Basic
	Handle(QIVtkSelectionPipeline) createBasicUnitActor(const TopoDS_Shape& shape, bool bAddToCache = false);

	// 更新Actor位置（因为pipeline的原理，更新位置会重新创建新的Actor）
	Handle(QIVtkSelectionPipeline) UpdateActorPosition(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& position, bool bAddToCache = false);

	// 平移Actor
	Handle(QIVtkSelectionPipeline) TranslateActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& delta, bool bAddToCache = false);

	// 旋转Actor
	Handle(QIVtkSelectionPipeline) RotateActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax1& axis, double angle, bool bAddToCache = false);

	// 对Actor实行变换
	Handle(QIVtkSelectionPipeline) TransformActor(Handle(QIVtkSelectionPipeline) actor, const gp_Trsf& transform, bool bAddToCache = false);

	// 布尔运算
	static TopoDS_Shape BooleanOperation(const TopoDS_Shape& targetShape, const TopoDS_Shape& toolShape, BooleanOP booleanStytle);

	// 创建临时球形Actor——用于点选择器
	vtkSmartPointer<vtkActor> CreateTempSphereActor(float radius, const gp_Pnt& position);
	// 移除临时Actor
	void RemoveTempActor(vtkSmartPointer<vtkActor> actor);
	// 创建一个actor，用于临时显示
	vtkSmartPointer<vtkActor> CreateTempActor(std::reference_wrapper<const TopoDS_Shape> shape);

	// Actor确认创建
	void OnActorConfirmCreate(Handle(QIVtkSelectionPipeline) actor);
	// 移除actor
	void RemoveActorFromRenderer(Handle(QIVtkSelectionPipeline) actor);
	// 移除所有的actor
	void RemoveAllActorsFromRenderer();
	// 移除选中的actor
	void RemoveSelectedActor(Handle(QIVtkSelectionPipeline) pipeline);
	// 取消选择actor
	void ClearSelectedActors();

	// 子窗口对操作的限制
	void SubWidgetClose(bool bIsConfirm);
	void SetSubWidgetSelected(bool selected);
	bool IsSubWidgetSelected();

	// 通过Actor获取Pipeline
	Handle(QIVtkSelectionPipeline) GetActorsOuterPipeline(vtkActor* InActor);
	// 刷新渲染
	void FlushRender();
	// 得到选择模式
	IVtk_SelectionMode GetSelectionMode() const;
	// 设置选择模式
	void SetSelectionMode(IVtk_SelectionMode mode);
	// 设置是否可以多选
	void SetCanMultiSelect(bool bCanMultiPick);
	// 获得当前选择的点
	void GetVertexPickerTargetPos(bool& bIsPick, gp_Pnt& Pos);
	// 获得选择的拓扑形状
	const std::vector<std::reference_wrapper<const TopoDS_Shape>> GetSelectedShapes();
	// 设置最大选中数量
	void SetMaxSelectedActors(uint maxSelectedActors);
	// 重置最大选中数量
	void ResetMaxSelectedActors();
	// 获取选中的Actor
	const std::vector<Handle(QIVtkSelectionPipeline)>& GetSelectedActors();
	// 获得当前所有的featureShape
	std::vector<std::shared_ptr<FeatureShape>> GetCurrentFeatureShapes();
	// 获得缓存的actors
	const std::vector<Handle(QIVtkSelectionPipeline)>& GetCachedActors() { return m_cacheActors; }
	// 选择指定的actor
	void SelectActor(Handle(QIVtkSelectionPipeline) pipeline, bool bClearSelected = false);
	// 获得featureshape对于的actor
    Handle(QIVtkSelectionPipeline) GetActorFromFeatureShape(std::shared_ptr<FeatureShape> featureShape);

	// 右键菜单事件
	void onRightClickMenu();

	// 删除选择的actors，可能被外部调用
	void onDeleteActionTriggered();
	// 编辑选择的actor(最后一个)，可能被外部调用
    void onEditActionTriggered();

	// 隐藏选择的actor
    void HideSelectedActors();
	// 对 cached actor 设置可视性
	void SetCachedActorVisibility(bool visible);

	//获得草图管理器
	QSketchManager* GetSketchManager() const { return m_sketchManager; }

	void SketchActionResponse(bool bStart);

protected:
	// 不同事件响应
	void onCubeActionTriggered();
	void onSphereActionTriggered();
	void onCylinderActionTriggered();
	void onTorusActionTriggered();
	void onConeActionTriggered();
 	void onLineActionTriggered();
	void onCircleActionTriggered();
	void onEllipseActionTriggered();
	void onParabolaActionTriggered();
	void onHyperbolaActionTriggered();
	void onBooleanActionTriggered();
	void onTransformActionTriggered();
	void onStretchActionTriggered();
	void onRevolveActionTriggered();
	void onRoundOffActionTriggered();
	void onHollowActionTriggered();
	void onRedo();
	void onUndo();
	void onEexpressionActionTriggered();
	void onSave();
	void onLoad();
	void onNew();
	void onFrontViewActionTriggered();
    void onBackViewActionTriggered();
    void onTopViewActionTriggered();
    void onLeftViewActionTriggered();
    void onRightViewActionTriggered();
    void onBottomViewActionTriggered();
	void onPositiveTriaxialViewActionTriggered();
	void onFitViewActionTriggered();
	void onSelectEdgeEndVertexActionTriggered();
    void onSelectEdgeDividedVertexActionTriggered();
	void onSelectFaceMidVertexActionTriggered();
	void onSelectIntersectionVertexActionTriggered();
	void onSelectCircleCenterVertexActionTriggered();
	void onSketchActionTriggered();
	void onFillActionTriggered();

	bool CheckCanSubWidget();

	// qt信号槽机制不允许payload(额外参数)，bind函数参数必须与slot一一对应，导致必须抽出create widget逻辑
	void CubeWidget(ShapeOperation* op = nullptr);
    void SphereWidget(ShapeOperation* op = nullptr);
    void CylinderWidget(ShapeOperation* op = nullptr);
    void TorusWidget(ShapeOperation* op = nullptr);
    void ConeWidget(ShapeOperation* op = nullptr);
    void LineWidget(ShapeOperation* op = nullptr);
    void CircleWidget(ShapeOperation* op = nullptr);
    void EllipseWidget(ShapeOperation* op = nullptr);
    void ParabolaWidget(ShapeOperation* op = nullptr);
    void HyperbolaWidget(ShapeOperation* op = nullptr);
    void BooleanWidget(ShapeOperation* op = nullptr);
    void TransformWidget(ShapeOperation* op = nullptr);
    void StretchWidget(ShapeOperation* op = nullptr);
    void RevolveWidget(ShapeOperation* op = nullptr);
    void RoundOffWidget(ShapeOperation* op = nullptr);
    void HollowWidget(ShapeOperation* op = nullptr);
	void FillWidget(ShapeOperation* op = nullptr);
	void CreateFromObjectWidget(ShapeOperation* op = nullptr);
	void DetachEdgeWidget(ShapeOperation* op = nullptr);
    void DetachFaceWidget(ShapeOperation* op = nullptr);
	void UncoverFaceWidget(ShapeOperation* op = nullptr);
	void CoverFaceWidget(ShapeOperation* op = nullptr);
	void MoveEdgeWidget(ShapeOperation* op = nullptr);
    void MoveFaceWidget(ShapeOperation* op = nullptr);
	void SectionWidget(ShapeOperation* op = nullptr);

	void redoOperation(ShapeOperation* op);

private:
	SARibbonBar* m_mainBar;
	SARibbonQuickAccessBar* m_quickAccessBar;

	void createQuickAccessBar();
	void createModelCategory();
	void createFileButton();
	void createViewCategoty();
	void createSketchCategory();

	QAction* createAction(const QString& text, const QString& iconurl, const QString& objName);
	QAction* createAction(const QString& text, const QString& iconurl);

// -----------------Override Begin-------------------
	virtual void closeEvent(QCloseEvent* event);
// -----------------Override End---------------------
public:
	HistoryManager* GetHistoryManager() const {return m_historyManager;}
	ExpressionManager* GetExpressionManager() const {return m_expressionManager;}
	vtkSmartPointer<WindowInteractorStyle> GetInteractorStyle() const { return m_interactorStyle; }
	vtkSmartPointer<vtkRenderer> GetRenderer() const { return m_renderer; }
	std::shared_ptr<TempActorManager> GetTempActorManager() const { return m_tempActorManager; }
private:
	Ui::MainWindowClass *ui;
	bool bHasSubWidget = false;
	bool bSubWidgetSelected = false;
	bool bSketchActionInProgress = false;

	// Cube单位建模
	QAction* cubeAction;
	// Sphere单位建模
	QAction* sphereAction;
	// Cylinder单位建模
	QAction* cylinderAction;
	// Torus单位建模
	QAction* torusAction;
	// Cone单位建模
	QAction* coneAction;
	// Line单位建模
	QAction* lineAction;
    // Circle单位建模
    QAction* circleAction;
	// Ellipse单位建模
	QAction* ellipseAction;
	// Parabola单位建模
	QAction* parabolaAction;
	// hyperbola单位建模
    QAction* hyperbolaAction;

	// bool运算
	QAction* booleanAction;
	// 平移运算
	QAction* translateAction;
	// 拉伸运算
	QAction* stretchAction;
	// 旋转运算
	QAction* rotateAction;
	// 倒圆角
 	QAction* roundOffAction;
	// 抽壳运算
    QAction* hollowAction;
	// 填充
	QAction* fillAction;

	// undo
    QAction* undoAction;
	// redo
    QAction* redoAction;

	// 表达式
    QAction* expressionAction;

	// 保存
    QAction* saveAction;
	// 加载
    QAction* loadAction;
	// 新建
	QAction* newAction;

	// 正视图
	QAction* frontView;
	// 右视图
    QAction* rightView;
	// 左视图
    QAction* leftView;
	// 后视图
    QAction* backView;
	// 仰视图
    QAction* topView;
	// 俯视图
    QAction* bottomView;
	// 正三轴视图
	QAction* positiveTriaxialView;
	// 适合视图
	QAction* fitView;

	// 删除操作
	QAction* deleteSelectActorsAction;
	// 编辑操作
    QAction* editActorAction;

	// 隐藏所有Actor
    QAction* hideAllActorsAction;
    // 显示所有Actor
    QAction* showAllActorsAction;
	// 隐藏选择的actors
	QAction* hideSelectAcotrAction;

	QAction* selectEdgeEndVertex;
    QAction* selectEdgeDividedVertex;
    QAction* selectFaceMidVertex;
    QAction* selectIntersectionVertex;
    QAction* selectCircleCenterVertex;

	// 草图action
	QAction* sketchAction;
	QAction* finishSketchAction;
	

	vtkGenericOpenGLRenderWindow* m_renderWindow;
	vtkSmartPointer<vtkRenderer> m_renderer;
	std::vector<Handle(QIVtkSelectionPipeline)> m_cacheActors;
	vtkSmartPointer<class WindowInteractor> m_interactor;
	vtkSmartPointer<class vtkPropPicker> m_propPicker;
	vtkSmartPointer<WindowInteractorStyle> m_interactorStyle;
	vtkSmartPointer<class IVtkTools_ShapePicker> m_shapePicker;
	vtkSmartPointer<class vtkTipsCoordinate> m_coord;

	QStandardItemModel* m_listModel;
	QListView* m_listView;
	HistoryManager* m_historyManager;
	ExpressionManager* m_expressionManager;
	std::vector<Handle(QIVtkSelectionPipeline)> m_hidedActors;

	vtkSmartPointer<class vtkCamera> m_camera;
	QSketchManager* m_sketchManager;
	std::shared_ptr<TempActorManager> m_tempActorManager;
//------------------Signal Begin-------------------
public slots:
	inline void SelectedActor(QIVtkSelectionPipeline* actor)
	{
		emit OnSelectedActor(actor);
	}
	inline void LeftButtonDown()
	{
		emit OnLeftButtonDown();
	}
	inline void SelectedSubShapes(QIVtkSelectionPipeline* actor)
	{
		emit OnSelectedSubShapes(actor);
	}
	inline void MouseMove(Standard_Integer theX, Standard_Integer theY)
	{
		emit OnMouseMove(theX, theY);
	}
	inline void PickActor(vtkActor* actor)
	{
        emit OnPickActor(actor);
	}
signals:
	void OnSelectedActor(QIVtkSelectionPipeline* actor);
	void OnLeftButtonDown();
	void OnSelectedSubShapes(QIVtkSelectionPipeline* actor);
	void OnMouseMove(Standard_Integer theX, Standard_Integer theY);
    void OnPickActor(vtkActor* actor);
//------------------Signal End---------------------
};
